﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Info;
using Microsoft.Phone.Shell;
using Com.PhilChuang.Utils;
using Com.PhilChuang.Pmvp.Utils;

namespace Com.PhilChuang.Mobile.Apps.LocationSender
{
	public partial class App : Application
	{
		/// <summary>
		/// Provides easy access to the root frame of the Phone Application.
		/// </summary>
		/// <returns>The root frame of the Phone Application.</returns>
		public PhoneApplicationFrame RootFrame { get; private set; }

		public static String DeviceName
		{
			get
			{
				object device;
				return Microsoft.Phone.Info.DeviceExtendedProperties.TryGetValue ("DeviceName", out device) ? device.ToString () : String.Empty;
			}
		}

		public static string PhoneId
		{
			get
			{
				var value = (byte[]) DeviceExtendedProperties.GetValue ("DeviceUniqueId");
				return Convert.ToBase64String (value);
			}
		}

		public static IDictionary<String, String> AnalyticsExtendedData
		{
			get
			{
				var d = new Dictionary<string, string> ();
				d["DeviceName"] = DeviceName;
				return d;
			}
		}

		public static bool RiOptIn
		{
			get
			{
				bool rioptin;
				if (!System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings.TryGetValue (
					Com.PhilChuang.Mobile.Apps.LocationSender.Ui.Views.Impl.ViewFacades.SettingsViewFacade.RI_OPT_IN, out rioptin))
				{
					// true by default
					System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings
						[Com.PhilChuang.Mobile.Apps.LocationSender.Ui.Views.Impl.ViewFacades.SettingsViewFacade.RI_OPT_IN] = true;
					return true;
				}
				return rioptin;
			}
		}
		
		/// <summary>
		/// Constructor for the Application object.
		/// </summary>
		public App ()
		{
			// Global handler for uncaught exceptions. 
			UnhandledException += Application_UnhandledException;

			// Show graphics profiling information while debugging.
			if (System.Diagnostics.Debugger.IsAttached)
			{
				// Display the current frame rate counters.
				//Application.Current.Host.Settings.EnableFrameRateCounter = true;

				// Show the areas of the app that are being redrawn in each frame.
				//Application.Current.Host.Settings.EnableRedrawRegions = true;

				// Enable non-production analysis visualization mode, 
				// which shows areas of a page that are being GPU accelerated with a colored overlay.
				//Application.Current.Host.Settings.EnableCacheVisualization = true;
			}

			// Standard Silverlight initialization
			InitializeComponent ();

			// Phone-specific initialization
			InitializePhoneApplication ();

			AppServiceLocator.Instance = new AppServiceLocatorImpl { Dispatcher = RootFrame.Dispatcher };
		}

		// Code to execute when the application is launching (eg, from Start)
		// This code will not execute when the application is reactivated
		private void Application_Launching (object sender, LaunchingEventArgs e)
		{
			((DefaultAppHelper) AppServiceLocator.Instance.GetImpl<IAppHelper> ()).OnAppLaunch ();
		}

		// Code to execute when the application is activated (brought to foreground)
		// This code will not execute when the application is first launched
		private void Application_Activated (object sender, ActivatedEventArgs e)
		{
			((DefaultAppHelper) AppServiceLocator.Instance.GetImpl<IAppHelper> ()).OnAppResume ();
		}

		// Code to execute when the application is deactivated (sent to background)
		// This code will not execute when the application is closing
		private void Application_Deactivated (object sender, DeactivatedEventArgs e)
		{
			((DefaultAppHelper) AppServiceLocator.Instance.GetImpl<IAppHelper> ()).OnAppSuspend ();
		}

		// Code to execute when the application is closing (eg, user hit Back)
		// This code will not execute when the application is deactivated
		private void Application_Closing (object sender, ClosingEventArgs e)
		{
			((DefaultAppHelper) AppServiceLocator.Instance.GetImpl<IAppHelper> ()).OnAppClose ();
		}

		// Code to execute if a navigation fails
		private void RootFrame_NavigationFailed (object sender, NavigationFailedEventArgs e)
		{
			if (System.Diagnostics.Debugger.IsAttached)
			{
				// A navigation has failed; break into the debugger
				System.Diagnostics.Debugger.Break ();
			}
		}

		// Code to execute on Unhandled Exceptions
		private void Application_UnhandledException (object sender, ApplicationUnhandledExceptionEventArgs e)
		{
			if (System.Diagnostics.Debugger.IsAttached)
			{
				// An unhandled exception has occurred; break into the debugger
				System.Diagnostics.Debugger.Break ();
			}

			var e2 = new HandledEventArgs<Exception> (e.ExceptionObject);
			((DefaultAppHelper) AppServiceLocator.Instance.GetImpl<IAppHelper> ()).OnUnhandledException (sender, e2);
			e.Handled = e2.Handled;
		}

		#region Phone application initialization

		// Avoid double-initialization
		private bool phoneApplicationInitialized = false;

		// Do not add any additional code to this method
		private void InitializePhoneApplication ()
		{
			if (phoneApplicationInitialized)
				return;

			// Create the frame but don't set it as RootVisual yet; this allows the splash
			// screen to remain active until the application is ready to render.
			RootFrame = new PhoneApplicationFrame ();
			RootFrame.Navigated += CompleteInitializePhoneApplication;

			// Handle navigation failures
			RootFrame.NavigationFailed += RootFrame_NavigationFailed;

			// Ensure we don't initialize again
			phoneApplicationInitialized = true;
		}

		// Do not add any additional code to this method
		private void CompleteInitializePhoneApplication (object sender, NavigationEventArgs e)
		{
			// Set the root visual to allow the application to render
			if (RootVisual != RootFrame)
				RootVisual = RootFrame;

			// Remove this handler since it is no longer needed
			RootFrame.Navigated -= CompleteInitializePhoneApplication;
		}

		#endregion
	}
}